package com.coincalf.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.coincalf.entity.User;
import com.coincalf.framework.enums.BaseStatus;
import com.coincalf.framework.enums.ResultCode;
import com.coincalf.framework.enums.UserType;
import com.coincalf.framework.exception.GlobalDefaultException;
import com.coincalf.framework.http.Response;
import com.coincalf.framework.utils.TokenUtil;
import com.coincalf.mapper.UserMapper;
import com.coincalf.service.AccountService;
import com.coincalf.service.UserService;
import com.coincalf.wallet.feign.UserInfoServiceClient;
import com.coincalf.wallet.feign.dto.UserInfoDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private AccountService accountService;

    //存在循环依赖
    @Lazy
    @Autowired
    private UserInfoServiceClient userInfoServiceClient;

    @Override
    public User selectByPhone(String phone) {
        EntityWrapper<User> ew = new EntityWrapper<>();
        ew.eq("mobile", phone);
        return super.selectOne(ew);
    }

    @Override
    public Object registerForPhp(String token) {
        //PHP那边注册的同时，PHP调用该接口 作用是将用户信息写入数据库
        //{"phoneCode":86,"iat":1611387354,"username":"15989001760"}
        Map<String, Object> map = TokenUtil.parserImToken(token);
        String phoneCode = String.valueOf(map.get("phoneCode"));
        String username = String.valueOf(map.get("username"));
        //String password = (String) map.get("password");
        if (StringUtils.isBlank(phoneCode) || StringUtils.isBlank(username)) {
            throw new GlobalDefaultException(-4);
        }

        User user = this.selectByPhone(username);
        if (user != null) {
            throw new GlobalDefaultException(40002);
        }
        user = new User();
        user.setCountryCode(phoneCode);
        user.setMobile(username);
        //JAVA这边不保存用户密码 避免token传输造成泄露
        user.setPassword(new BCryptPasswordEncoder().encode("")); // 密码
        user.setLogins(0);                              // 登录次数
        user.setStatus(BaseStatus.EFFECTIVE.getCode()); // 状态
        user.setGaStatus(0);                            // 谷歌身份验证状态 默认0未启用
        user.setPaypassSetting(0);                      // 支付密码
        user.setType(UserType.CUSTOMER.getCode());      // 类型为：普通用户
        user.setLevel(-1);                              // 普通用户层级为-1
        user.setCreated(new Date());
        int count = baseMapper.insert(user);
        if (count > 0) {
            Long userId = user.getId();
            baseMapper.updateById(user);
            //初始化资金账户 和 外汇账户
            boolean initAccount = accountService.syncAccount(userId);
            if (!initAccount) {
                log.warn("初始化资金账户或外汇账户失败");
                throw new GlobalDefaultException(2007);
            }
            //初始钱包库用户基本信息
            UserInfoDTO userInfo = new UserInfoDTO();
            userInfo.setId(userId)
                    .setCountryCode(user.getCountryCode())
                    .setUsername(username)
                    .setMobile(user.getMobile());
            boolean initUserInfo = userInfoServiceClient.addUserInfo(userInfo);
            if (!initUserInfo) {
                log.warn("初始钱包库用户基本信息失败");
                throw new GlobalDefaultException(2007);
            }
            return Response.ok();
        }
        return Response.err(ResultCode.ERROR);
    }

}
